package thread.queue.condition;

import thread.queue.Store;
import thread.queue.Consumer;
import thread.queue.Producer;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;


/**
 * Created by xu on 2021/12/5.
 */
public class StoreCondition implements Store {
    //最大保存限制
    private final  int MAX_LIMIT = 10;
    private List<String> list = new ArrayList();
    Lock lock = new ReentrantLock();
    private Condition consumeCondition = lock.newCondition();
    private Condition produceCondition = lock.newCondition();




    @Override
    public void produce(String t) throws InterruptedException {
        try{
            lock.lock();
            if(list.size()>MAX_LIMIT){
                System.out.println("生产过量等待消费者消费----"+list.size());
                produceCondition.await();
            }else {
                System.out.println("生产资源:"+Thread.currentThread().getId()+",param:"+t.toString() +",size:"+list.size());
                list.add(t);
                consumeCondition.signal();
            }
        }finally {
            lock.unlock();
        }
    }

    @Override
    public void consume() throws InterruptedException {
        try{
            lock.lock();
            if(list.size()>0){
                //消费
                String t = list.get(0);
                System.out.println("消费资源："+t+",size:"+list.size());
                Thread.sleep(1000);
                list.remove(0);
                produceCondition.signal();
            }else {
                System.out.println("暂无资源可以消费----"+list.size());
                consumeCondition.await();
            }
        }finally {
            lock.unlock();
        }

    }

    public static void main(String[] args) {
        Store store = new StoreCondition();

        Producer p1 =  new Producer(store);
        Producer p2 =  new Producer(store);
        Producer p3 =  new Producer(store);
        new  Thread(p1).start();
        new  Thread(p2).start();
        new  Thread(p3).start();
        Consumer c1 =  new Consumer(store);
        new  Thread(c1).start();

    }


}
